// 接收主进程消息
(function (e) {
    /*************************************************** 操作事件 *********************************************************/
    // 点击事件对象
    const clickHandle = e.clickHandle = {}
    // 服务列表
    let services = {}

    // 加载历史数据
    // setTimeout(() => {
    loadCache()
    // }, 1000)

    // 启动
    clickHandle.serviceStart = () => {
        const port = getInputValue('hostPort')
        if (!port) return tipMessage('请输入端口号')
        sendToIpcMain('serviceStart', port)
    }

    // 关闭
    clickHandle.serviceClose = () => {
        const port = getInputValue('hostPort')
        if (!port) return tipMessage('关闭失败')
        sendToIpcMain('serviceClose', port)
    }

    // 新建
    clickHandle.serviceNew = () => {
        setInputValue('hostName', null)
        setInputValue('hostPort', null)

        setInnerText('host', '')

        setSelectValue('proxyRouteMethod', '*')
        setInputValue('proxyRoutePath', null)
        setInputValue('proxyRouteAddr', null)

        pageSateShow(false)
        updateRuleShow([])
    }

    // 删除
    clickHandle.serviceDel = () => {
        const port = getInputValue('hostPort')
        if (port) {
            clickHandle.serviceNew()
            sendToIpcMain('serviceDel', port)
        }
    }

    // 删除所有
    clickHandle.serviceDelAll = () => {
        sendToIpcMain('serviceDelAll')
    }

    // 添加路由
    clickHandle.addProxyRoute = () => {
        const port = getInputValue('hostPort')
        const method = getSelectValue('proxyRouteMethod')
        const path = getInputValue('proxyRoutePath')
        const url = getInputValue('proxyRouteAddr')

        // 验证
        if (!path) return tipMessage('请输入路由规则')
        if (!url) return tipMessage('请输入目标地址')

        sendToIpcMain('routeAdd', { port, path, url, method })
    }

    // 删除路由
    clickHandle.delProxyRoute = (port, path, method) => {
        sendToIpcMain('routeDel', { port, path, method })
    }

    // 选择服务
    clickHandle.service = (index, port) => {
        const listEl = document.getElementsByClassName('list-item');
        [...listEl].forEach((el, i) => {
            if (i == index) el.style.borderColor = '#cccccc'
            else el.style.borderColor = '#ffffff'
        })

        setInputValue('hostPort', port)
        setInputValue('hostName', services[port].name)
        setInnerText('host', `地址：${services[port].host[0]} ; ${services[port].host[1]}`)

        const routes = storeReady('routes')
        updateRoutes(routes)
        pageSateShow(services[port].state)
    }

    /*************************************************** 更新显示 *********************************************************/
    // 加载缓存
    function loadCache() {
        const routes = storeReady('routes')
        const s = storeReady('services')

        // 显示服务列表
        if (s) {
            services = s
            for (const key in services) services[key].state = false
            updateServicesShow(services)
        }

        if (routes) {
            // 显示第一个服务
            const k = Object.keys(routes)
            const port = k[0]
            if (port) {
                setInputValue('hostPort', port)
                setInputValue('hostName', services[port].name)
                updateRoutes(routes)
            }
            // 初始化路由
            sendToIpcMain('routeInit', routes)
        }
    }

    // 显示服务
    function updateRoutes(routes) {
        if (routes) {
            const port = getInputValue('hostPort')
            const service = routes[port]

            if (service) updateRuleShow(routes, port)
            else updateRuleShow([])

            // 加入缓存
            if (Object.keys(routes).length == 0) routes = null
            storeSave('routes', routes)
        }
    }

    // 显示服务列表
    function updateServicesShow(services) {
        let htmlStr = ''
        let i = 0;
        for (const port in services) {
            const item = services[port]
            htmlStr += `<span class='list-item ${item.state ? 'list-item-active' : ''}' onClick="clickHandle.service(${i}, ${port})">${item.name ? item.name : port}</span>`
            i++
        }
        setInnerHTML('list', htmlStr)

        // 加入缓存
        if (Object.keys(services).length == 0) services = null
        storeSave('services', services)
    }

    // 更新路由规则列表
    function updateRuleShow(routes, port) {
        let htmlStr = ''
        if (routes[port]) {
            for (const route in routes[port]) {
                for (const method in routes[port][route]) {
                    htmlStr += `<p class='routes-item'>
                    <span class='routes-item-method'>${method}</span>
                    <span class='routes-item-path'>${route}</span>
                    <span style="padding: 0 20px;"> -&gt; </span>
                    <span class='routes-item-url'>${routes[port][route][method]}</span>
                    <button class='routes-item-del' onClick="clickHandle.delProxyRoute(${port},'${route}','${method}')">删除</button>
                </p>`
                }
            }

        }
        setInnerHTML('routes', htmlStr)
    }

    // 根据服务状态，调整页面渲染状态
    function pageSateShow(state) {
        if (state) {
            document.getElementById('hostName').disabled = true
            document.getElementById('hostPort').disabled = true
            document.getElementById('serviceStart').disabled = true
            document.getElementById('serviceClose').disabled = false
            document.getElementById('proxyRouteMethod').disabled = false
            document.getElementById('proxyRoutePath').disabled = false
            document.getElementById('proxyRouteAddr').disabled = false
            document.getElementById('addProxyRoute').disabled = false
        } else {
            document.getElementById('hostName').disabled = false
            document.getElementById('hostPort').disabled = false
            document.getElementById('serviceStart').disabled = false
            document.getElementById('serviceClose').disabled = true
            document.getElementById('proxyRouteMethod').disabled = true
            document.getElementById('proxyRoutePath').disabled = true
            document.getElementById('proxyRouteAddr').disabled = true
            document.getElementById('addProxyRoute').disabled = true
        }
    }

    /*************************************************** 与主进程通讯部分 ***************************************************/
    /**
     * 发送消息到主进程
     * @param {String} eventName 消息名称
     * @param {String} data 消息数据
     */
    function sendToIpcMain(eventName, data) {
        if (window.electronAPI && window.electronAPI[eventName]) window.electronAPI[eventName](data)
        else console.error('[发送消息到主进程失败]', eventName, data)
    }

    /**
     * 接收主进程消息
     * @param {String} eventName 消息名称
     * @param {Function} callback 监听回调
     */
    function receiveToIpcMain(eventName, callback) {
        window.electronAPI[eventName]((_event, data) => {
            callback(data)
        })
    }

    // 服务启动成功
    receiveToIpcMain('serviceStartSuccess', addr => {
        const name = getInputValue('hostName')
        const port = addr.port
        const service = {
            name,
            host: [
                `http://localhost:${port}`,
                `http://${addr.ipAddr}:${port}`
            ],
            state: true
        }
        setInnerText('host', `${service.host[0]} ; ${service.host[1]}`)

        services[port] = service
        updateServicesShow(services)
        pageSateShow(service.state)
    })

    // 服务关闭成功
    receiveToIpcMain('serviceCloseSuccess', port => {
        setInnerText('host', '')
        services[port].state = false
        updateServicesShow(services)
        pageSateShow(services[port].state)
    })

    // 服务删除成功
    receiveToIpcMain('serviceDelSuccess', data => {
        setInnerText('host', '')
        const { port, routes } = data
        delete services[port]
        updateServicesShow(services)
        updateRoutes(routes)
        pageSateShow(false)
    })

    // 服务删除所有
    receiveToIpcMain('serviceDelAllSuccess', routes => {
        for (const port in services) {
            delete services[port]
        }
        updateServicesShow([])
        clickHandle.serviceNew()
        localStorage.clear()
    })

    // 添加路由成功
    receiveToIpcMain('routeAddSuccess', routes => updateRoutes(routes))

    // 删除路由成功
    receiveToIpcMain('routeDelSuccess', routes => updateRoutes(routes))

    // 初始路由表
    receiveToIpcMain('routeInitSuccess', routes => updateRoutes(routes))

    /*************************************************** 辅助方法 *********************************************************/
    /**
     * 获取input输入数据
     * @param {String} id 元素id
     * @returns 
     */
    function getInputValue(id) {
        return document.getElementById(id).value.trim()
    }

    /**
     * 设置input输入数据
     * @param {String} id 元素id
     * @param {String} val 元素value
     * @returns 
     */
    function setInputValue(id, val) {
        document.getElementById(id).value = val
    }

    /**
     * 获取select选择值
     * @param {String} id 元素id
     * @returns 
     */
    function getSelectValue(id) {
        const el = document.getElementById(id)
        return el.value
    }

    /**
     * 设置select选择值
     * @param {String} id 元素id
     * @param {String} val 元素value
     * @returns 
     */
    function setSelectValue(id, val) {
        const el = document.getElementById(id)
        el.value = val
    }

    /**
     * 设置元素内容
     * @param {String} id 元素id
     * @param {String} str 填充内容
     */
    function setInnerText(id, str) {
        const hostEl = document.getElementById(id)
        hostEl.innerText = str
    }

    /**
     * 元素插入html
     * @param {String} id 元素id
     * @param {String} str 填充html
     */
    function setInnerHTML(id, str) {
        const hostEl = document.getElementById(id)
        hostEl.innerHTML = str
    }

    /**
     * 持久存储
     * @param {String} name 名称
     * @param {String} data 数据
     */
    function storeSave(name, data) {
        const dd = JSON.stringify(data)
        localStorage.setItem(name, dd)
    }

    /**
     * 读取存储
     * @param {String} name 名称
     * @returns 
     */
    function storeReady(name) {
        const dd = localStorage.getItem(name)
        return JSON.parse(dd)
    }

    /**
     * 提示消息
     * @param {String} message 消息内容
     */
    function tipMessage(message) {
        const el = document.createElement('div')
        el.setAttribute('class', 'tip-message')
        el.innerText = message
        document.body.appendChild(el)
        setTimeout(() => document.body.removeChild(el), 2000)
    }
})(window)